{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Python范儿：Coding Pythonically"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 数学定义：解析(Comprehensions，或称推导式)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 让代码飞\n",
    "\n",
    "找到0-9之间的偶数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 2, 4, 6, 8]\n"
     ]
    }
   ],
   "source": [
    "#number = range(10)\n",
    "size = 10\n",
    "even_numbers = []\n",
    "\n",
    "n = 0\n",
    "while n < size:\n",
    "    if n % 2==0:\n",
    "         even_numbers.append(n)\n",
    "    n += 1\n",
    "print even_numbers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们做的事情在数学定义上看来像是什么呢？\n",
    "\n",
    "$\\{x|x \\in \\{0,1,2,....,9\\}, s.t. x\\%2==0 \\}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0, 2, 4, 6, 8}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{ x for x in range(10) if x % 2==0 }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这种代码形式称为Comprehensions，也就是解析（推导式）。\n",
    "\n",
    "形式： {expr(item) for item in iterable if cond_expr(item)} 或者中括号、小括号包裹\n",
    "\n",
    "* 第一部分：元素，对元素的操作（运算与函数都可以）\n",
    "* 第二部分：遍历行为\n",
    "* 第三部分：筛选条件（可选）\n",
    "* 最后：用小括号，中括号，大括号包含住三部分，得到不同的数据结构或对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n"
     ]
    }
   ],
   "source": [
    "print [ x**2 for x in xrange(10)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 1.2 使用中括号进行列表解析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "回忆enumerate\n",
    "\n",
    "任务：把一个list里的元素和索引号找出来，更新回原来的list中去\n",
    "\n",
    "**循环操作可变类型**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<type 'enumerate'> <enumerate object at 0x1042d17d0>\n",
      "['0:Ainur', '1:Dragons', '2:Dwarves', '3:Elves', '4:Ents', '5:Hobbits', '6:Men', '7:Orcs']\n"
     ]
    }
   ],
   "source": [
    "Lord_of_ring = ['Ainur','Dragons','Dwarves','Elves','Ents','Hobbits','Men','Orcs']\n",
    "\n",
    "print type(enumerate(Lord_of_ring)),enumerate(Lord_of_ring)\n",
    "\n",
    "for idx,element in enumerate(Lord_of_ring):\n",
    "    Lord_of_ring[idx] =\"{0}:{1}\".format(idx,element)\n",
    "\n",
    "print Lord_of_ring"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**List Comprehension构造新列表**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['0:Ainur', '1:Dragons', '2:Dwarves', '3:Elves', '4:Ents', '5:Hobbits', '6:Men', '7:Orcs']\n",
      "['0:Ainur', '1:Dragons', '2:Dwarves', '3:Elves', '4:Ents', '5:Hobbits', '6:Men', '7:Orcs']\n"
     ]
    }
   ],
   "source": [
    "test =['Ainur','Dragons','Dwarves','Elves','Ents','Hobbits','Men','Orcs']\n",
    "\n",
    "def _trans(idx,element):\n",
    "    return '{0}:{1}'.format(idx,element)\n",
    "print [_trans(idx,element) for idx,element in enumerate(test)]\n",
    "\n",
    "print ['{0}:{1}'.format(idx,element) for idx,element in enumerate(test) ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**老朋友Iterable，isinstance()检查**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "import collections\n",
    "\n",
    "print isinstance(\"Hello,world\",   collections.Iterable)\n",
    "print isinstance( test,           collections.Iterable)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典也是Iterable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Standard ML  created by Robin Milner   ',\n",
       " 'C            created by Dennis Ritchie ',\n",
       " 'Clojure      created by Richy Hickey   ',\n",
       " 'Scala        created by Martin Odersky ']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "language={\"Scala\":\"Martin Odersky\",\\\n",
    "          \"Clojure\":\"Richy Hickey\",\\\n",
    "          \"C\":\"Dennis Ritchie\",\\\n",
    "          \"Standard ML\":\"Robin Milner\"}\n",
    "\n",
    "['{0:<12} created by {1:<15}'.format(la,ua)\\\n",
    " for la,ua in language.iteritems()]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**多重解析**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)]\n",
      "[(2, 1), (3, 1), (3, 2), (4, 1), (4, 2), (4, 3)]\n",
      "[(2, 1), (3, 1), (3, 2), (4, 1), (4, 2), (4, 3)]\n"
     ]
    }
   ],
   "source": [
    "print [(x+1,y+1) for x in xrange(4) for y in xrange(4)]\n",
    "print [(x+1,y+1) for x in xrange(4) for y in xrange(4) if y<x]\n",
    "print [(x+1,y+1) for x in xrange(4) for y in xrange(x)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 使用小括号进行生成器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用小括号做Comprehension返回生成器对象，占用O(1)内存空间："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<generator object <genexpr> at 0x1043e9dc0>\n",
      "1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361\n"
     ]
    }
   ],
   "source": [
    "num=range(0,20)\n",
    "\n",
    "simple_generator=(x**2 for x in num if x > 0)\n",
    "\n",
    "print simple_generator\n",
    "\n",
    "for element in simple_generator:\n",
    "    print element,"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 使用大括号解析得到集合或字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用小括号解析并不会返回一个不可变元组而是生成器，是一个需要强记的规则；然而大括号解析式就普通了许多。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set([0, 8, 2, 4, 6])\n",
      "{0: 0, 8: 64, 2: 4, 4: 16, 6: 36}\n"
     ]
    }
   ],
   "source": [
    "x = range(10)\n",
    "\n",
    "print { i for i in x if i%2==0 }\n",
    "print { idx:i**2 for idx,i in enumerate(x) if i%2==0 }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意生成字典时使用key:value的形式就可以了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2 花样传参：zip与星号操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* zip: 拉链函数\n",
    "* \\*: 经常和zip在一起，用于传递参数。\n",
    "* \\*\\*: 用于传递关键字型参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 Zip(拉链)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* enumerate: 返回生成器，生成器每次给出下标和Iterable的内容\n",
    "* sorted: 返回列表，可以进行排序\n",
    "* zip: 把多个长度相同的列表当成数据列组成的数据表，返回一个包含着元组的列表，每个元组是数据表中的一行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('Orc', 'Blade Master'), ('Humans', 'Archmage'), ('Undead', 'Death King'), ('Night Elves', 'Demon Hunter')]\n"
     ]
    }
   ],
   "source": [
    "war3_char = ['Orc','Humans','Undead','Night Elves']\n",
    "dota_hero = ['Blade Master','Archmage','Death King','Demon Hunter']\n",
    "Your_choice=zip(war3_char,dota_hero)\n",
    "print Your_choice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "取回原来的列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('Orc', 'Humans', 'Undead', 'Night Elves'), ('Blade Master', 'Archmage', 'Death King', 'Demon Hunter')]\n"
     ]
    }
   ],
   "source": [
    "choice1,choice2,choice3,choice4 = Your_choice\n",
    "print zip(choice1,choice2,choice3,choice4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用\\*把Your_choice的内容而不是它本身作为参数传递"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('Orc', 'Humans', 'Undead', 'Night Elves'), ('Blade Master', 'Archmage', 'Death King', 'Demon Hunter')]\n"
     ]
    }
   ],
   "source": [
    "print zip(*Your_choice)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\* 告诉Python即将传入的参数Your_choice不是单独一个序列，而是把Your_choice中的每一项作为参数\n",
    "\n",
    "从下面的字典里按值来排序，取到值最大或者值最小的那条记录："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(48, 'Blade Master'), (65, 'Death King'), (51, 'Tauren Chieftain')]\n",
      "(65, 'Death King') (48, 'Blade Master')\n"
     ]
    }
   ],
   "source": [
    "Base_Damage={'Blade Master':48,'Death King':65,'Tauren Chieftain':51}\n",
    "print zip(Base_Damage.itervalues(),Base_Damage.iterkeys())\n",
    "max_Damage=max(zip(Base_Damage.itervalues(),Base_Damage.iterkeys()))\n",
    "min_Damage=min(zip(Base_Damage.itervalues(),Base_Damage.iterkeys()))\n",
    "\n",
    "print max_Damage,min_Damage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**花样传参**\n",
    "    \n",
    "刚才已经知道能把列表加星号保持有序地作为一个个参数（argument）传给方法/函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "123\n"
     ]
    }
   ],
   "source": [
    "def triplesum(a,b,c):\n",
    "    return a*100+b*10+c\n",
    "\n",
    "print triplesum(*[1,2,3])\n",
    "print triplesum(1,2,3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "带默认值的参数叫keyword arguments(kargs):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "1235\n",
      "1235678\n",
      "130\n",
      "123\n",
      "103\n"
     ]
    }
   ],
   "source": [
    "def triplesum_default(a=0,b=0,c=0,*args):\n",
    "    return a*100+b*10+c\n",
    "\n",
    "def ntuplesum_default(*args):\n",
    "    sum = 0\n",
    "    for i in args:\n",
    "        sum*=10\n",
    "        sum+=i\n",
    "    return sum\n",
    "\n",
    "print triplesum_default(*[1,2,3,4])\n",
    "print ntuplesum_default(*[1,2,3,5])\n",
    "print ntuplesum_default(1,2,3,5,6,7,8)\n",
    "print triplesum_default(*[1,3])\n",
    "print triplesum_default(**{'b':2,'c':3,'a':1})\n",
    "print triplesum_default(**{'c':3,'a':1})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3 变量之变：深浅拷贝"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "深浅拷贝：关系到变量的正确修改与复制\n",
    "\n",
    "变量的属性：\n",
    "\n",
    "* 身份：就像身份证（或者内存地址）那样，id()\n",
    "* 属性：表示变量的类型，type()或者isInstance()确认\n",
    "* 值：这个地址存的数据，通过与名字绑定的方法来读取"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 浅拷贝\n",
    "* 完全切片(Slicing)操作[:]\n",
    "* 工厂函数，比如list(),tuple()\n",
    "* copy中的copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4361778168, 4361777736, 4371155352, 4371155424]\n",
      "[4297703024, 4297703024, 4297703024, 4297703024]\n",
      "[4361686984, 4361686984, 4361686984, 4361686984]\n"
     ]
    }
   ],
   "source": [
    "import copy\n",
    "unit = ['name',['Base_Damage',65.00]]\n",
    "my_hero = unit[:]               #使用切片拷贝\n",
    "your_hero = list(unit)          #使用工厂方法拷贝\n",
    "its_hero = copy.copy(unit)      #使用浅拷贝\n",
    "print [id(x) for x in unit,my_hero,your_hero,its_hero]\n",
    "print [id(x[0]) for x in unit,my_hero,your_hero,its_hero]\n",
    "print [id(x[1]) for x in unit,my_hero,your_hero,its_hero]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假设一下，你的英雄打到了豪华套装（your_hero),或者游戏中的英雄（my_hero)有了一个嗜血的加成效果，所以数值会出现一些不一样的地方。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"Kel'Thuzad\", ['Base_Damage', 65.0]] ['Mirana', ['Base_Damage', 65.0]] ['Morphling', ['Base_Damage', 65.0]]\n",
      "[\"Kel'Thuzad\", ['Base_Damage', 100.0]] ['Mirana', ['Base_Damage', 100.0]] ['Morphling', ['Base_Damage', 100.0]]\n"
     ]
    }
   ],
   "source": [
    "my_hero[0] = 'Kel\\'Thuzad'\n",
    "your_hero[0] = 'Mirana'\n",
    "its_hero[0] = 'Morphling'\n",
    "print my_hero,your_hero,its_hero\n",
    "my_hero[1][1]=100.00                   # 先更改一个对象的值\n",
    "print my_hero,your_hero,its_hero       #  可以看出值的情况不对，my_hero"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "为什么相互影响了呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4297703024, 4371530688, 4371530928, 4371530784]\n",
      "[4361686984, 4361686984, 4361686984, 4361686984]\n"
     ]
    }
   ],
   "source": [
    "print [id(x[0]) for x in unit,my_hero,your_hero,its_hero]\n",
    "print [id(x[1]) for x in unit,my_hero,your_hero,its_hero]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 第一个对象是不可变的（字符串），而且还重新被赋值\n",
    "* 而第二个对象是可变的（一个列表），而且修改的是第二个对象里面的内容，第二个对象本身指向的地址不变"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 资深玩家的选择：深拷贝"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"Kel'Thuzad\", ['Base_Damage', [100.0]]] ['Mirana', ['Base_Damage', [65.0]]]\n"
     ]
    }
   ],
   "source": [
    "import copy\n",
    "unit = ['name',['Base_Damage',[65.00]]]\n",
    "my_hero = copy.deepcopy(unit)\n",
    "your_hero = copy.deepcopy(unit)\n",
    "\n",
    "my_hero[0] = 'Kel\\'Thuzad'\n",
    "your_hero[0] = 'Mirana'\n",
    "my_hero[1][1][0] = 100.00           \n",
    "\n",
    "print my_hero,your_hero"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 用id( )验证一下"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4371530880, 4361851032]\n",
      "[4371531024, 4361851248]\n"
     ]
    }
   ],
   "source": [
    "print [id(x) for x in my_hero]\n",
    "print [id(x) for x in your_hero]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 不想Debug太烦？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 规避修改复杂可变类型内容，维护唯一拷贝\n",
    "* 规避使用可变类型\n",
    "* 理解Clojure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4 异常处理：Try-Except-Else-Finally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**会犯错的是人，能原谅人的是……**\n",
    "\n",
    "* try\n",
    "* except\n",
    "* finally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python允许程序在运行当中检测错误。\n",
    "\n",
    "每检测到一个错误，Python解释器就引发一个异常并报出详细的错误信息："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "integer division or modulo by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-11-76b625659a29>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;36m1\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
     ]
    }
   ],
   "source": [
    "y = 6\n",
    "x = 5\n",
    "x,y = y,x\n",
    "1/0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 我们执行了一个除零操作（这显然是非法的），报出了\"ZeroDivisionError: integer division or modulo by zero\"\n",
    "* 在使用Python编写程序时，认真查看报错信息\n",
    "* 建议多使用Ipython notebook 完成小代码块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 4.1 基本用法：try-except Exception"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果你需要添加错误检测和异常处理，需要把你想要书写的代码组封装在try-except语句中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wow, such cute error\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    x = 1/0\n",
    "    y = range(10)[10]\n",
    "except Exception:\n",
    "    print \"Wow, such cute error\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 笔下无错，心中有错"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "常见的python中的异常，举例来说：\n",
    "* 有上文中已经出现的除零错误（ZeroDivisionError）\n",
    "* 尝试访问未声明的变量（NameError）\n",
    "* 语法错误    （Syntax Error）\n",
    "* 请求索引超过索引范围  （IndexError，常见于切片操作中）\n",
    "* 输入/输出错误  （IOError）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wow, such cute divisor\n",
      "integer division or modulo by zero\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    x = 1/0\n",
    "    y = range(10)[10] \n",
    "except ZeroDivisionError,e1:\n",
    "    print \"Wow, such cute divisor\"\n",
    "except IndexError,e2:\n",
    "    print \"Wow, such cute index\"\n",
    "    \n",
    "print e1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wow, such cute index\n",
      "list index out of range\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    x = 1/2\n",
    "    y = range(10)[10] \n",
    "except ZeroDivisionError,e1:\n",
    "    print \"Wow, such cute divisor\"\n",
    "except IndexError,e2:\n",
    "    print \"Wow, such cute index\"\n",
    "    \n",
    "print e2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 异常处理：完全体"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过try-except-else-finally来感受异常处理的完全体吧！\n",
    "\n",
    "* try 下面是可能有异常的代码块\n",
    "* except 下面是对异常的处理\n",
    "* else 下面是在并没有异常的时候执行的代码块\n",
    "* finally 下面是收尾工作，无论是否有异常都执行\n",
    "\n",
    "并用另一种方式记录异常。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X,Y is corrected.\n",
      "162\n",
      "Finished\n",
      "\n",
      "integer division or modulo by zero \n",
      "<type 'exceptions.ZeroDivisionError'> \n",
      "integer division or modulo by zero \n",
      "<traceback object at 0x1047b9a28> 4\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "\n",
    "try:\n",
    "    x = 1/0\n",
    "    y = range(10)[-1]\n",
    "except Exception,error:\n",
    "    x = 0\n",
    "    y = 9\n",
    "    print 'X,Y is corrected.'\n",
    "    info = sys.exc_info()\n",
    "else:\n",
    "    print 'Catch no exceptions. Great!'\n",
    "finally:\n",
    "    z = x + y\n",
    "    print z**2 + x**2 + y**2\n",
    "    print 'Finished'\n",
    "    \n",
    "print '\\n',error,'\\n',info[0],'\\n',info[1],'\\n',info[2],info[2].tb_lineno\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
